package com.concurrent.data.thread.service.impl;

import com.concurrent.data.thread.bean.AddOrderReqBean;
import com.concurrent.data.thread.dao.ConsumerDao;
import com.concurrent.data.thread.dao.GoodsDao;
import com.concurrent.data.thread.dao.GoodsOrderDao;
import com.concurrent.data.thread.entity.Goods;
import com.concurrent.data.thread.entity.GoodsOrder;
import com.concurrent.data.thread.service.GoodsOrderService;
import com.concurrent.data.thread.utils.FastJsonUtil;
import com.concurrent.data.thread.utils.RedisUtil;
import lombok.SneakyThrows;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * @author 哲思小辉
 * @version 1.0.0
 * @ClassName GoodsOrderServiceImpl.java
 * @Description 订单服务接口实现
 * @Param
 * @createTime 2020年03月25日 20:35:00
 */
@Service
public class GoodsOrderServiceImpl implements GoodsOrderService {
    @Resource
    private GoodsOrderDao goodsOrderDao;

    @Resource
    private GoodsDao goodsDao;

    @Autowired
    private ConsumerDao consumerDao;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public GoodsOrder queryById(Integer id) {
        return this.goodsOrderDao.queryById(id);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Override
    public List<GoodsOrder> queryAllByLimit(int offset, int limit) {
        return this.goodsOrderDao.queryAllByLimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @param goodsOrder 实例对象
     * @return 实例对象
     */
    @Override
    public GoodsOrder insert(GoodsOrder goodsOrder) {
        this.goodsOrderDao.insert(goodsOrder);
        return goodsOrder;
    }

    /**
     * 修改数据
     *
     * @param goodsOrder 实例对象
     * @return 实例对象
     */
    @Override
    public GoodsOrder update(GoodsOrder goodsOrder) {
        this.goodsOrderDao.update(goodsOrder);
        return this.queryById(goodsOrder.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        return this.goodsOrderDao.deleteById(id) > 0;
    }

    @SneakyThrows
    @Override
    public GoodsOrder addOrder(AddOrderReqBean addOrderReqBean) {

        val goodsId = addOrderReqBean.getGoodsId();
        val userId = addOrderReqBean.getUserId();
        val amount = addOrderReqBean.getAmount();
        val goods = getGoods(goodsId);
        if (goods == null) {
            throw new Exception("商品不存在");
        }
        String key = "order" + addOrderReqBean.getGoodsId();
        System.out.println(RedisUtil.tryLock(key));

        val goodsStatus = goods.getGoodsStatus();
        if (Objects.equals(goodsStatus, 0)) {
            throw new Exception("商品已下架");
        }
        if (Objects.equals(goodsStatus, 1)) {
            throw new Exception("商品还未开始售卖");
        }

        val promotionAmount = goods.getPromotionAmount();
        val unitPrice = goods.getUnitPrice();
        val discount = goods.getDiscount();
        val discountPrice = unitPrice * discount;
        val totalAmount = goods.getTotalAmount();

        val goodsOrder = new GoodsOrder();
        goodsOrder.setGoodsId(goodsId);
        goodsOrder.setAmount(amount);
        goodsOrder.setOrderStatus(1);
        goodsOrder.setUserId(userId);
        goods.setTotalAmount(totalAmount - amount);

        val consumer = consumerDao.queryById(Integer.valueOf(userId));
        if (consumer == null) {
            throw new Exception("用户不存在");
        }

        if (promotionAmount > 0 && amount < promotionAmount) {
            goodsOrder.setUnitPrice(discountPrice);
            goodsOrder.setTotalPrice(amount * discountPrice);
            goods.setPromotionAmount(promotionAmount - amount);
        } else if (amount <= totalAmount) {
            goodsOrder.setUnitPrice(unitPrice);
            goodsOrder.setTotalPrice(amount * unitPrice);
        } else {
            throw new Exception("库存不足");
        }

        val accountBalance = consumer.getAccountBalance();
        if (accountBalance < goodsOrder.getTotalPrice()) {
            throw new Exception("账户余额不够支付");
        }

        consumer.setAccountBalance(accountBalance - goodsOrder.getTotalPrice());
        // 更新商品，订单，用户
        goodsDao.update(goods);
        consumerDao.update(consumer);
        goodsOrderDao.insert(goodsOrder);
        RedisUtil.unLock(key);
        return goodsOrder;
    }

    private Goods getGoods(Integer goodsId) {
        val key = "goods_" + goodsId;
        val goods = RedisUtil.get(key, Goods.class);
        if (goods == null) {
            boolean b = RedisUtil.tryLock("goods_lock_id_" + goodsId);
            if (b) {
                val goo = goodsDao.queryById(goodsId);
                if (goo != null) {
                    RedisUtil.set(goodsId, FastJsonUtil.toJson(goo));
                }
            } else {
//                goods = getGoods(goodsId);
            }
        }
        return goods;
    }
}